---
title: Collections de contenus
description: >-
  Gérez votre contenu avec la sûreté du typage.
i18nReady: true
---
import { FileTree, CardGrid, LinkCard, Steps } from '@astrojs/starlight/components';
import Since from '~/components/Since.astro'
import RecipeLinks from "~/components/RecipeLinks.astro"
import Badge from "~/components/Badge.astro"
import ReadMore from "~/components/ReadMore.astro"

<p><Since v="2.0.0" /></p>

**Les collections de contenu** sont le meilleur moyen de gérer des ensembles de contenu dans n'importe quel projet Astro. Les collections aident à organiser et à interroger vos documents, à activer Intellisense et la vérification de type dans votre éditeur et à fournir une sûreté du typage TypeScript automatique pour tout votre contenu.
Astro v5.0 a introduit l'API de couche de contenu pour définir et interroger les collections de contenu. Cette API performante et évolutive fournit des chargeurs de contenu intégrés pour vos collections locales. Pour le contenu distant, vous pouvez utiliser des chargeurs tiers et créés par la communauté ou créer votre propre chargeur personnalisé et extraire vos données à partir de n'importe quelle source.

:::note
Les projets peuvent continuer à utiliser l'API de collections de contenu héritée introduite dans Astro v2.0. Cependant, nous vous encourageons à [mettre à jour les collections existantes](/fr/guides/upgrade-to/v5/#héritage--api-des-collections-de-contenu-de-la-v20) lorsque vous le pouvez.
:::

## Que sont les collections de contenu ?

Vous pouvez définir une **collection** à partir d'un ensemble de données structurellement similaires. Il peut s'agir d'un répertoire d'articles de blog, d'un fichier JSON de produits ou de toute donnée représentant plusieurs éléments de la même forme.

Les collections stockées localement dans votre projet ou sur votre système de fichiers peuvent contenir des entrées de fichiers Markdown, MDX, Markdoc, YAML, TOML ou JSON :

<FileTree>
- src/
- **newsletter/** la collection « newsletter »
  - week-1.md une entrée de collection
  - week-2.md une entrée de collection
  - week-3.md une entrée de collection
- **authors/** la collection « author »
  - authors.json un fichier unique contenant toutes les entrées de la collection
</FileTree>

Avec un chargeur de collection approprié, vous pouvez récupérer des données distantes à partir de n'importe quelle source externe, telle qu'un CMS, une base de données ou un système de paiement headless.

## Configuration TypeScript pour les collections

Les collections de contenu s'appuient sur TypeScript pour fournir la validation avec Zod, Intellisense et la vérification de type dans votre éditeur. Si vous n'étendez pas l'un des paramètres TypeScript `strict` ou `strictest` d'Astro, vous devrez vous assurer que `compilerOptions` définisse les options suivantes dans votre fichier `tsconfig.json` :

```json title="tsconfig.json" ins={5} {6}
{
  // Inclus avec "astro/tsconfigs/strict" ou "astro/tsconfigs/strictest"
  "extends": "astro/tsconfigs/base",
  "compilerOptions": {
    "strictNullChecks": true, // ajouter si vous utilisez le modèle `base`
    "allowJs": true // requis et inclus avec tous les modèles Astro
  }
}
```

## Définition des collections

Les collections individuelles utilisent `defineCollection()` pour configurer :
- un chargeur (`loader`) pour une source de données (obligatoire)
- un schéma (`schema`) pour la sûreté du typage (facultatif, mais fortement recommandé !)

### Le fichier de configuration des collections

Pour définir des collections, vous devez créer un fichier `src/content.config.ts` dans votre projet (les extensions `.js` et `.mjs` sont également prises en charge). Il s'agit d'un fichier spécial qu'Astro utilisera pour configurer vos collections de contenu en fonction de la structure suivante :

```ts title="src/content.config.ts"
// 1. Importer des utilitaires depuis `astro:content`
import { defineCollection, z } from 'astro:content';

// 2. Importer un ou plusieurs chargeurs
import { glob, file } from 'astro/loaders';

// 3. Définir votre/vos collection(s)
const blog = defineCollection({ /* ... */ });
const dogs = defineCollection({ /* ... */ });

// 4. Exporter un seul objet « collections » pour enregistrer votre/vos collection(s)
export const collections = { blog, dogs };
```

### Définir le chargeur de collection (`loader`)

L'API de couche de contenu vous permet de récupérer votre contenu (qu'il soit stocké localement dans votre projet ou à distance) et utilise une propriété `loader` pour récupérer vos données.

#### Chargeurs intégrés

Astro fournit [deux fonctions de chargement intégrées](/fr/reference/content-loader-reference/#types-de-chargeurs) (`glob()` et `file()`) pour récupérer votre contenu local, ainsi qu'un accès à l'API pour créer votre propre chargeur et récupérer des données distantes.

Le [chargeur `glob()`](/fr/reference/content-loader-reference/#le-chargeur-glob) crée des entrées à partir de répertoires de fichiers Markdown, MDX, Markdoc, JSON, YAML ou TOML à partir de n'importe quel endroit du système de fichiers. Il accepte un motif (`pattern`) de fichiers d'entrée à faire correspondre à l'aide de motifs glob pris en charge par [micromatch](https://github.com/micromatch/micromatch#matching-features) et un chemin de fichier `base` indiquant où se trouvent vos fichiers. L'`id` de chaque entrée sera automatiquement généré à partir de son nom de fichier. Utilisez ce chargeur lorsque vous avez un fichier par entrée.

Le [chargeur `file()`](/fr/reference/content-loader-reference/#le-chargeur-file) crée plusieurs entrées à partir d'un seul fichier local. Chaque entrée du fichier doit avoir un nom de propriété `id` unique. Il accepte un chemin de fichier `base` vers votre fichier et éventuellement une [fonction `parser`](#fonction-parser) pour les fichiers de données qu'il ne peut pas analyser automatiquement. Utilisez ce chargeur lorsque votre fichier de données peut être analysé comme un tableau d'objets.

```ts  title="src/content.config.ts" {5,9}
import { defineCollection, z } from 'astro:content';
import { glob, file } from 'astro/loaders'; // Non disponible avec l'API héritée

const blog = defineCollection({
  loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),
  schema: /* ... */
});
const dogs = defineCollection({
  loader: file("src/data/dogs.json"),
  schema: /* ... */
});

const probes = defineCollection({
  // `loader` peut accepter un tableau de plusieurs modèles ainsi que des modèles de chaîne de caractères
  // Chargez tous les fichiers Markdown dans le répertoire space-probes, à l'exception de ceux qui commencent par « voyager- »
  loader: glob({ pattern: ['*.md', '!voyager-*'], base: 'src/data/space-probes' }),
  schema: z.object({
    name: z.string(),
    type: z.enum(['Space Probe', 'Mars Rover', 'Comet Lander']),
    launch_date: z.date(),
    status: z.enum(['Actif', 'Inactif', 'Déclassé']),
    destination: z.string(),
    operator: z.string(),
    notable_discoveries: z.array(z.string()),
  }),
});

export const collections = { blog, dogs, probes };
```

##### Fonction `parser`

Le chargeur `file()` accepte un second argument qui définit une fonction d'analyse (`parser`). Cela vous permet de spécifier un analyseur personnalisé (par exemple `csv-parse`) pour créer une collection à partir du contenu d'un fichier.

Le chargeur `file()` détectera et analysera automatiquement (en fonction de leur extension de fichier) un seul tableau d'objets à partir de fichiers JSON et YAML, et traitera chaque table de niveau supérieur comme une entrée indépendante dans les fichiers TOML. La prise en charge de ces types de fichiers est intégrée, et aucun analyseur (`parser`) n'est nécessaire, sauf si vous disposez d'un [document JSON imbriqué](#documents-json-imbriqués). Pour utiliser d'autres fichiers, comme `.csv`, vous devrez créer une fonction d'analyse.

L'exemple suivant montre l'importation d'un analyseur CSV, puis le chargement d'une collection `cats` dans votre projet en transmettant à la fois un chemin de fichier et une fonction `parser` au chargeur `file()` :

```typescript title="src/content.config.ts"
import { defineCollection } from "astro:content";
import { file } from "astro/loaders";
import { parse as parseCsv } from "csv-parse/sync";

const cats = defineCollection({
  loader: file("src/data/cats.csv", { parser: (text) => parseCsv(text, { columns: true, skipEmptyLines: true })})
});
```

###### Documents `.json` imbriqués

L'argument `parser` vous permet également de charger une seule collection à partir d'un document JSON imbriqué. Par exemple, ce fichier JSON contient plusieurs collections :

```json title="src/data/pets.json"
{"dogs": [{}], "cats": [{}]}
```

Vous pouvez séparer ces collections en passant un analyseur personnalisé (`parser`) au chargeur `file()` pour chaque collection :

```typescript title="src/content.config.ts"
const dogs = defineCollection({
  loader: file("src/data/pets.json", { parser: (text) => JSON.parse(text).dogs })
});
const cats = defineCollection({
  loader: file("src/data/pets.json", { parser: (text) => JSON.parse(text).cats })
});
```

#### Créer un chargeur personnalisé

Vous pouvez créer un chargeur personnalisé pour récupérer du contenu distant à partir de n'importe quelle source de données, telle qu'un CMS, une base de données ou un point de terminaison d'API.

L'utilisation d'un chargeur pour récupérer vos données créera automatiquement une collection à partir de vos données distantes. Cela vous offre tous les avantages des collections locales, tels que les assistants API spécifiques aux collections tels que `getCollection()` et `render()` pour interroger et afficher vos données, ainsi que la validation de schéma.

:::tip
Recherchez des chargeurs créés par la communauté et des tiers dans le [répertoire des intégrations Astro](https://astro.build/integrations/?search=&categories%5B%5D=loaders).
:::

##### Chargeurs incorporés

Vous pouvez définir un chargeur incorporé, à l'intérieur de votre collection, comme une fonction asynchrone qui renvoie un tableau d'entrées.

Ceci est utile pour les chargeurs qui n'ont pas besoin de contrôler manuellement la manière dont les données sont chargées et stockées. Chaque fois que le chargeur est appelé, il efface le magasin et recharge toutes les entrées.

```ts title="src/content.config.ts"
const countries = defineCollection({
  loader: async () => {
    const response = await fetch("https://restcountries.com/v3.1/all");
    const data = await response.json();
    // Doit renvoyer un tableau d'entrées contenant une propriété id ou un objet avec des ID comme noms de propriété et des entrées comme valeurs
    return data.map((country) => ({
      id: country.cca3,
      ...country,
    }));
  },
  schema: /* ... */
});
```

Les entrées renvoyées sont stockées dans la collection et peuvent être interrogées à l'aide des fonctions `getCollection()` et `getEntry()`.

##### Objets de chargement

Pour un meilleur contrôle du processus de chargement, vous pouvez utiliser l'API de chargement de contenu pour créer un objet de chargement. Par exemple, avec un accès direct à la méthode `load`, vous pouvez créer un chargeur qui permet de mettre à jour les entrées de manière incrémentielle ou d'effacer le magasin uniquement lorsque cela est nécessaire.

Similairement à la création d'une intégration pour Astro ou d'un module d'extension pour Vite, vous pouvez [distribuer votre chargeur sous forme de paquet NPM](/fr/reference/publish-to-npm/) que d'autres peuvent utiliser dans leurs projets.

<ReadMore>Consultez [l'API de couche de contenu complète](/fr/reference/content-loader-reference/) et des exemples pour créer votre propre chargeur.</ReadMore>

### Définition d'un schéma de collection

Les schémas garantissent la cohérence des données du frontmatter ou d'entrée au sein d'une collection via la validation Zod. Un schéma **garantit** que ces données existent sous une forme prévisible lorsque vous devez les référencer ou les interroger. Si un fichier viole son schéma de collection, Astro fournira une erreur utile pour vous en informer.

Les schémas alimentent également les typages automatiques TypeScript d'Astro pour votre contenu. Lorsque vous définissez un schéma pour votre collection, Astro génère et applique automatiquement une interface TypeScript. Le résultat est une prise en charge complète de TypeScript lorsque vous interrogez votre collection, y compris la saisie semi-automatique des propriétés et la vérification des types.

:::tip
Pour qu'Astro reconnaisse un schéma nouveau ou mis à jour, vous devrez peut-être redémarrer le serveur de développement ou [synchroniser la couche de contenu](/fr/reference/cli-reference/#astro-dev) (<code>s + Entrée</code>) pour définir le module `astro:content`.
:::

Chaque frontmatter ou propriété de données de vos entrées de collection doit être défini à l’aide d’un type de données Zod :

```ts title="src/content.config.ts" {6-11,15-19}
import { defineCollection, z } from 'astro:content';
import { glob, file } from 'astro/loaders'; // Non disponible avec l'API héritée

const blog = defineCollection({
  loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
  })
});
const dogs = defineCollection({
  loader: file("src/data/dogs.json"),
  schema: z.object({
    id: z.string(),
    breed: z.string(),
    temperament: z.array(z.string()),
  }),
});

export const collections = { blog, dogs };
```

#### Définition des types de données avec Zod

Astro utilise [Zod](https://github.com/colinhacks/zod) pour alimenter ses schémas de contenu. Avec Zod, Astro est capable de valider les données de chaque fichier au sein d'une collection *et* de fournir des types TypeScript automatiques lorsque vous interrogez le contenu à partir de votre projet.

Pour utiliser Zod dans Astro, importez l'utilitaire `z` depuis `"astro:content"`. Il s'agit d'une réexportation de la bibliothèque Zod, et elle prend en charge toutes les fonctionnalités de Zod.

```ts
// Exemple : une aide-mémoire de nombreux types de données Zod courants
import { z, defineCollection } from 'astro:content';

defineCollection({
  schema: z.object({
    isDraft: z.boolean(),
    title: z.string(),
    sortOrder: z.number(),
    image: z.object({
      src: z.string(),
      alt: z.string(),
    }),
    author: z.string().default('Anonyme'),
    language: z.enum(['en', 'es']),
    tags: z.array(z.string()),
    footnote: z.string().optional(),

    // En YAML, les dates écrites sans guillemets sont interprétées comme des objets Date
    publishDate: z.date(), // par exemple 2024-09-17

    // Transformer une chaîne de date (par exemple « 2022-07-08 ») en objet Date
    updatedDate: z.string().transform((str) => new Date(str)),

    authorContact: z.string().email(),
    canonicalURL: z.string().url(),
  })
})
```

<ReadMore>Consultez [le fichier README de Zod](https://github.com/colinhacks/zod) pour obtenir une documentation complète sur le fonctionnement de Zod et les fonctionnalités disponibles.</ReadMore>

##### Méthodes de schéma Zod

Toutes [les méthodes de schéma Zod](https://zod.dev/?id=schema-methods) (p. ex. `.parse()`, `.transform()`) sont disponibles, avec certaines limitations. Notamment, l'exécution de contrôles de validation personnalisés sur les images à l'aide de `image().refine()` n'est pas prise en charge.

#### Définition des références de collection

Les entrées de collection peuvent également « faire référence » à d’autres entrées associées.

Avec la [fonction `reference()`](/fr/reference/modules/astro-content/#reference) de l'API des collections, vous pouvez définir une propriété dans un schéma de collection en tant qu'entrée d'une autre collection. Par exemple, vous pouvez exiger que chaque entrée `space-shuttle` inclue une propriété `pilot` qui utilise le schéma propre à la collection `pilot` pour la vérification du type, la saisie semi-automatique et la validation.

Un exemple courant est un article de blog qui fait référence à des profils d'auteur réutilisables stockés au format JSON ou à des URL d'articles associés stockées dans la même collection :

```ts title="src/content.config.ts"
import { defineCollection, reference, z } from 'astro:content';
import { glob } from 'astro/loaders';

const blog = defineCollection({
  loader: glob({ pattern: '**/[^_]*.md', base: "./src/data/blog" }),
  schema: z.object({
    title: z.string(),
    // Faire référence à un seul auteur de la collection `authors` par `id`
    author: reference('authors'),
    // Faire référence à un tableau d'articles connexes de la collection `blog` par `slug`
    relatedPosts: z.array(reference('blog')),
  })
});

const authors = defineCollection({
  loader: glob({ pattern: '**/[^_]*.json', base: "./src/data/authors" }),
  schema: z.object({
    name: z.string(),
    portfolio: z.string().url(),
  })
});

export const collections = { blog, authors };
```

Cet exemple d'article de blog spécifie les `id` des articles associés et l'`id` de l'auteur de l'article :

```yaml title="src/data/blog/welcome.md"
---
title: "Bienvenue sur mon blog"
author: ben-holmes # fait référence à `src/data/authors/ben-holmes.json` 
relatedPosts:
- about-me # fait référence à `src/data/blog/about-me.md`
- my-year-in-review # fait référence à `src/data/blog/my-year-in-review.md`
---
```

Ces références seront transformées en objets contenant une propriété `collection` et une propriété `id`, vous permettant de [les interroger facilement dans vos modèles](/fr/guides/content-collections/#accès-aux-données-référencées).

### Définition d'identifiants personnalisés

Lors de l'utilisation du chargeur `glob()` avec des fichiers Markdown, MDX, Markdoc ou JSON, chaque [`id`](/fr/reference/modules/astro-content/#id) d'entrée de contenu est automatiquement généré dans un format compatible URL basé sur le nom du fichier de contenu. L'`id` est utilisé pour interroger l'entrée directement à partir de votre collection. Il est également utile lors de la création de nouvelles pages et URL à partir de votre contenu.

Vous pouvez remplacer l'`id` généré par une entrée en ajoutant votre propre propriété `slug` au frontmatter du fichier ou à l'objet de données pour les fichiers JSON. Ceci est similaire à la fonctionnalité « permalien » d'autres frameworks Web.

```md title="src/blog/1.md" {3}
---
title: Mon article de blog
slug: mon-id-personnalise/prend-en-charge/les-barres-obliques
---
Le contenu de votre article de blog ici.
```

```json title="src/categories/1.json" {3}
{
  "title": "Ma catégorie",
  "slug": "mon-id-personnalise/prend-en-charge/les-barres-obliques",
  "description": "Votre description de catégorie ici."
}
```

## Interroger les collections

Astro fournit des fonctions d'aide pour interroger une collection et renvoyer une (ou plusieurs) entrées de contenu.

- [`getCollection()`](/fr/reference/modules/astro-content/#getcollection) récupère une collection entière et renvoie un tableau d'entrées.
- [`getEntry()`](/fr/reference/modules/astro-content/#getentry) récupère une seule entrée d'une collection.

Ces entrées de retour contiennent un `id` unique, un objet `data` avec toutes les propriétés définies et renverront également un `body` contenant le corps brut et non compilé d'un document Markdown, MDX ou Markdoc.

```js
import { getCollection, getEntry } from 'astro:content';

// Obtenir toutes les entrées d'une collection.
// Nécessite le nom de la collection comme argument.
const allBlogPosts = await getCollection('blog');

// Obtenir une seule entrée d’une collection.
// Nécessite le nom de la collection et un `id`
const poodleData = await getEntry('dogs', 'poodle');


```

L'ordre de tri des collections générées est non déterministe et dépend de la plateforme. Cela signifie que si vous appelez `getCollection()` et que vous avez besoin que vos entrées soient renvoyées dans un ordre spécifique (par exemple, des articles de blog triés par date), vous devez trier vous-même les entrées de la collection :

```astro title="src/pages/blog.astro"
---
import { getCollection } from 'astro:content';

const posts = (await getCollection('blog')).sort(
  (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
);
---
```

<ReadMore>Voir la liste complète des propriétés renvoyées par le [type `CollectionEntry`](/fr/reference/modules/astro-content/#collectionentry).</ReadMore>

### Utilisation du contenu dans les modèles Astro

Après avoir interrogé vos collections, vous pouvez accéder au contenu de chaque entrée directement dans votre modèle de composant Astro. Par exemple, vous pouvez créer une liste de liens vers vos articles de blog, en affichant les informations du frontmatter de votre entrée à l'aide de la propriété `data`.


```astro title="src/pages/index.astro"
---
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
---
<h1>Mes articles</h1>
<ul>
  {posts.map(post => (
    <li><a href={`/blog/${post.id}`}>{post.data.title}</a></li>
  ))}
</ul>
```
#### Restitution du contenu

Une fois la requête effectuée, vous pouvez restituer les entrées Markdown et MDX en HTML à l'aide de la propriété de fonction [`render()`](/fr/reference/modules/astro-content/#render). L'appel de cette fonction vous donne accès au contenu HTML restitué, y compris un composant `<Content />` et une liste de tous les titres restitués.

```astro title="src/pages/blog/post-1.astro" {5,8}
---
import { getEntry, render } from 'astro:content';

const entry = await getEntry('blog', 'post-1');
if (!entry) {
  // Traiter l'erreur, par exemple :
  throw new Error("Impossible de trouver l'article de blog 1");
}
const { Content, headings } = await render(entry);
---
<p>Publié le : {entry.data.published.toDateString()}</p>
<Content />
```

<ReadMore>Lorsque vous travaillez avec des entrées MDX, vous pouvez également [transmettre vos propres composants à `<Content />`](/fr/guides/integrations-guide/mdx/#transmettre-des-composants-au-contenu-mdx) pour remplacer les éléments HTML par des alternatives personnalisées.</ReadMore>

#### Transmettre du contenu en tant que props

Un composant peut également transmettre une entrée de collection entière en tant que propriété.

Vous pouvez utiliser l'utilitaire [`CollectionEntry`](/fr/reference/modules/astro-content/#collectionentry) pour saisir correctement les propriétés de votre composant à l'aide de TypeScript. Cet utilitaire prend en tant qu'argument une chaîne de caractères qui correspond au nom de votre schéma de collection et héritera de toutes les propriétés du schéma de cette collection.

```astro title="src/components/BlogCard.astro" /CollectionEntry(?:<.+>)?/
---
import type { CollectionEntry } from 'astro:content';
interface Props {
  post: CollectionEntry<'blog'>;
}

// `post` correspondra au type de schéma de votre collection 'blog'
const { post } = Astro.props;
---
```

### Filtrer les requêtes sur les collections

`getCollection()` prend une fonction de rappel facultative « filter » qui vous permet de filtrer votre requête en fonction des propriétés `id` ou `data` d'une entrée.

Vous pouvez utiliser cette propriété pour filtrer selon n'importe quel critère de contenu. Par exemple, vous pouvez filtrer par des propriétés telles que `draft` pour empêcher la publication d'un brouillon d'article sur votre blog :

```js
// Exemple : Filtrer les entrées de contenu avec `draft: true` (brouillon : vrai)
import { getCollection } from 'astro:content';
const publishedBlogEntries = await getCollection('blog', ({ data }) => {
  return data.draft !== true;
});
```

Vous pouvez également créer des pages provisoires qui sont disponibles lors de l'exécution du serveur de développement, mais qui ne sont pas générées en production :

```js
// Exemple : Filtrer les entrées de contenu avec `draft: true` uniquement lors de la compilation pour la production
import { getCollection } from 'astro:content';
const blogEntries = await getCollection('blog', ({ data }) => {
  return import.meta.env.PROD ? data.draft !== true : true;
});
```

L'argument `filter` permet également de filtrer les répertoires imbriqués dans une collection. Puisque `id` inclut le chemin imbriqué complet, vous pouvez filtrer en utilisant le début de chaque `id` pour ne renvoyer que les éléments d'un répertoire imbriqué spécifique :

```js
// Exemple : Filtrer les entrées par sous-répertoire dans la collection
import { getCollection } from 'astro:content';
const englishDocsEntries = await getCollection('docs', ({ id }) => {
  return id.startsWith('en/');
});
```

### Accès aux données référencées

Toutes [références définies dans votre schéma](/fr/guides/content-collections/#définition-des-références-de-collection) doivent être interrogées séparément après la première interrogation de votre entrée de collection. Puisque la [fonction `reference()`](/fr/reference/modules/astro-content/#reference) transforme une référence en un objet avec `collection` et `id` comme propriétés, vous pouvez utiliser la fonction `getEntry()` pour renvoyer un seul élément référencé ou `getEntries()` pour récupérer plusieurs entrées référencées à partir de l'objet `data` renvoyé.

```astro title="src/pages/blog/welcome.astro"
---
import { getEntry, getEntries } from 'astro:content';

const blogPost = await getEntry('blog', 'welcome');

// Restituer une seule référence (p. ex. `{collection: "authors", id: "ben-holmes"}`)
const author = await getEntry(blogPost.data.author);
// Restituer un tableau de références
// (p. ex. `[{collection: "blog", id: "about-me"}, {collection: "blog", id: "my-year-in-review"}]`)
const relatedPosts = await getEntries(blogPost.data.relatedPosts);
---

<h1>{blogPost.data.title}</h1>
<p>Auteur : {author.data.name}</p>

<!-- ... -->

<h2>Vous pourriez aussi aimer :</h2>
{relatedPosts.map(post => (
  <a href={post.id}>{post.data.title}</a>
))}
```

## Générer des routes à partir du contenu

Les collections de contenu sont stockées en dehors du répertoire `src/pages/`. Cela signifie qu'aucune page ou route n'est générée par défaut pour vos éléments de collection.

Vous devrez créer manuellement une nouvelle [route dynamique](/fr/guides/routing/#routes-dynamiques) si vous souhaitez générer des pages HTML pour chacune de vos entrées de collection, telles que des articles de blog individuels. Votre route dynamique va mettre en correspondance le paramètre de la requête entrante (p. ex. : `Astro.params.slug` dans `src/pages/blog/[...slug].astro`) pour récupérer la bonne entrée à l'intérieur d'une collection.

La méthode exacte de génération des routes dépendra du fait que vos pages sont pré-rendues (par défaut) ou rendues à la demande par un serveur.

### Créer pour une sortie statique (par défaut)

Si vous créez un site web statique (comportement par défaut d'Astro), utilisez la fonction [`getStaticPaths()`](/fr/reference/routing-reference/#getstaticpaths) pour créer plusieurs pages à partir d'un seul composant de page (par exemple `src/pages/[slug]`) au moment de la compilation.

Appelez `getCollection()` à l'intérieur de `getStaticPaths()` pour que vos données de collection soient disponibles pour la création de routes statiques. Ensuite, créez les chemins d'URL individuels à l'aide de la propriété `id` de chaque entrée de contenu. Chaque page reçoit l'entrée de collection entière en tant que propriété à [utiliser dans votre modèle de page](#utilisation-du-contenu-dans-les-modèles-astro).

```astro title="src/pages/posts/[id].astro" "{ id: post.id }" "{ post }"
---
import { getCollection, render } from 'astro:content';
// 1. Génére un nouveau chemin pour chaque entrée de collection
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map(post => ({
    params: { id: post.id },
    props: { post },
  }));
}
// 2. Pour votre modèle, vous pouvez obtenir l'entrée directement à partir de la propriété
const { post } = Astro.props;
const { Content } = await render(post);
---
<h1>{post.data.title}</h1>
<Content />
```

Cela générera une route de page pour chaque entrée de la collection `blog`. Par exemple, une entrée dans `src/blog/hello-world.md` possèdera un `id` avec la valeur `hello-world`, ainsi son URL finale sera `/posts/hello-world/`.

:::note
Si vos slugs personnalisés contiennent le caractère `/` pour produire des URLs avec plusieurs segments de chemin, vous devez utiliser un [paramètre du reste (par exemple `[...slug]`)](/fr/guides/routing/#paramètres-du-reste) dans le nom de fichier `.astro` pour cette page de routage dynamique.
:::

### Créer pour une sortie serveur (SSR)

Si vous créez un site web dynamique (en utilisant la prise en charge SSR d'Astro), vous n'êtes pas censé générer des chemins à l'avance pendant la compilation. Au lieu de cela, votre page devrait examiner la requête (en utilisant `Astro.request` ou `Astro.params`) pour obtenir le `slug` demandé, et ensuite récupérer l'entrée en utilisant [`getEntry()`](/fr/reference/modules/astro-content/#getentry).


```astro title="src/pages/posts/[id].astro"
---
import { getEntry, render } from "astro:content";
// 1. Récupérer le slug de la requête entrante du serveur
const { id } = Astro.params;
if (id === undefined) {
	return Astro.redirect("/404");
}
// 2. Interroger l'entrée directement à l'aide du slug de requête
const post = await getEntry("blog", id);
// 3. Redirection si l'entrée n'existe pas
if (post === undefined) {
	return Astro.redirect("/404");
}
// 4. Effecter le rendu de l'entrée en HTML dans le modèle
const { Content } = await render(post);
---
<h1>{post.data.title}</h1>
<Content />
```

:::tip
Explorez le dossier `src/pages/` du [code de démonstration du tutoriel du blog sur GitHub](https://github.com/withastro/blog-tutorial-demo/tree/content-collections/src/pages) pour voir des exemples complets de création de pages à partir de vos collections pour des fonctionnalités de blog telles qu'une liste d'articles de blog, des pages de balises, etc.
:::

## Schémas JSON de collection

<p><Since v="4.13.0" /></p>

Astro génère automatiquement des fichiers de [schéma JSON](https://json-schema.org/) pour les collections, que vous pouvez utiliser dans votre éditeur pour obtenir IntelliSense et la vérification de type pour les fichiers de données.

Un fichier de schéma au format JSON est généré pour chaque collection de votre projet et envoyé dans le répertoire `.astro/collections/`. Par exemple, si vous avez deux collections, l'une nommée `authors` et l'autre `posts`, Astro générera `.astro/collections/authors.schema.json` et `.astro/collections/posts.schema.json`.

### Utiliser des schémas JSON dans les fichiers JSON

Vous pouvez pointer manuellement vers un schéma généré par Astro en définissant le champ `$schema` dans votre fichier JSON.
La valeur doit être un chemin d'accès au schéma relatif au fichier de données.
Dans l'exemple suivant, un fichier de données dans `src/data/authors/` utilise le schéma généré pour la collection `authors` :

```json title="src/data/authors/armand.json" ins={2}
{
  "$schema": "../../../.astro/collections/authors.schema.json",
  "name": "Armand",
  "skills": ["Astro", "Starlight"]
}
```

#### Utiliser un schéma pour un groupe de fichiers JSON dans VS Code

Dans VS Code, vous pouvez configurer un schéma applicable à tous les fichiers d'une collection grâce au [paramètre `json.schemas`](https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings).
Dans l'exemple suivant, tous les fichiers du répertoire `src/data/authors/` utiliseront le schéma généré pour la collection `authors` :

```json
{
  "json.schemas": [
    {
      "fileMatch": ["/src/data/authors/**"],
      "url": "./.astro/collections/authors.schema.json"
    }
  ]
}
```

### Utiliser des schémas dans les fichiers YAML dans VS Code

Dans VS Code, vous pouvez ajouter la prise en charge des schémas JSON dans les fichiers YAML grâce à l'extension [Red Hat YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml).
Une fois cette extension installée, vous pouvez référencer un schéma dans un fichier YAML à l'aide d'une syntaxe de commentaire spécifique :

```yaml title="src/data/authors/armand.yml" ins={1}
# yaml-language-server: $schema=../../../.astro/collections/authors.schema.json
name: Armand
skills:
  - Astro
  - Starlight
```

#### Utiliser des schémas pour un groupe de fichiers YAML dans VS Code

Avec l'extension Red Hat YAML, vous pouvez configurer un schéma applicable à tous les fichiers YAML d'une collection grâce au paramètre `yaml.schemas`.
Dans l'exemple suivant, tous les fichiers YAML du répertoire `src/data/authors/` utiliseront le schéma généré pour la collection `authors` :

```json
{
  "yaml.schemas": {
    "./.astro/collections/authors.schema.json": ["/src/content/authors/*.yml"]
  }
}
```

Consultez [« Association de schémas »](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml#associating-schemas) dans la documentation de l'extension Red Hat YAML pour plus de détails.

## Quand créer une collection

Vous pouvez [créer une collection](#définition-des-collections) à chaque fois que vous disposez d'un groupe de données ou de contenus associés qui partagent une structure commune.

Une grande partie des avantages liés à l’utilisation des collections provient de :

- La définition d'une structure de données commune pour valider qu'une entrée individuelle est « correcte » ou « complète », évitant ainsi les erreurs de production.
- API axées sur le contenu conçues pour rendre les requêtes intuitives (par exemple, `getCollection()` au lieu de `import.meta.glob()`) lors de l'importation et du rendu du contenu sur vos pages.
- Une [API de chargement de contenu](/fr/reference/content-loader-reference/) pour récupérer votre contenu qui fournit à la fois des chargeurs intégrés et un accès à l'API de bas niveau. Il existe plusieurs chargeurs tiers et communautaires disponibles, et vous pouvez créer votre propre chargeur personnalisé pour récupérer des données de n'importe où.
- La performance et l'évolutivité. L'API de couche de contenu permet de mettre en cache les données entre les compilations et convient à des dizaines de milliers d'entrées de contenu.

[Définissez vos données](#définition-des-collections) comme une collection lorsque :

- Vous avez plusieurs fichiers ou données à organiser qui partagent la même structure globale (par exemple, des articles de blog écrits en Markdown qui ont tous les mêmes propriétés de frontmatter).
- Vous disposez d'un contenu existant stocké à distance, par exemple dans un CMS, et vous souhaitez profiter des fonctions d'assistance des collections et de l'API de couche de contenu au lieu d'utiliser `fetch()` ou des SDK.
- Vous devez récupérer (des dizaines de) milliers de données connexes et avez besoin d'une méthode d'interrogation et de mise en cache capable de gérer à grande échelle.

### Quand ne pas créer une collection

Les collections offrent une excellente structure, sécurité et organisation lorsque vous avez **plusieurs éléments de contenu qui doivent partager les mêmes propriétés**.

Les collections **ne sont peut-être pas votre solution** si :

- Vous n'avez qu'une seule page ou un petit nombre de pages différentes. Envisagez plutôt de [créer des composants de page individuels](/fr/basics/astro-pages/) tels que `src/pages/about.astro` directement avec votre contenu.
- Vous affichez des fichiers qui ne sont pas traités par Astro, comme des fichiers PDF. Placez plutôt ces ressources statiques dans le [répertoire `public/`](/fr/basics/project-structure/#public) de votre projet.
- Votre source de données possède sa propre bibliothèque SDK/client pour les importations qui est incompatible avec ou n'offre pas de chargeur de contenu et vous préférez l'utiliser directement.
- Vous utilisez des API qui doivent être mises à jour en temps réel. Les collections de contenu ne sont mises à jour qu'au moment de la création. Par conséquent, si vous avez besoin de données en direct, utilisez d'autres méthodes d'[importation de fichiers](/fr/guides/imports/#instructions-dimportation) ou de [récupération de données](/fr/guides/data-fetching/) avec le [rendu à la demande](/fr/guides/on-demand-rendering/).
